Conversation
…s and avoiding descendant traversal when there has been no change to the node's URL segment.
There was a problem hiding this comment.
Pull request overview
This PR improves redirect tracking reliability/performance during publish operations by detecting URL-segment changes (to avoid unnecessary descendant traversal) and fixes invariant-culture URL segment lookups so redirects are correctly created when invariant content is renamed.
Changes:
- Add URL-segment change detection for publishes (with an
isMoveflag to preserve always-traverse semantics for moves) and batch de-duplication during redirect route capture. - Fix invariant-content segment lookups in
DocumentUrlServicewhen culture is""(and related invariant fallbacks). - Fix
DefaultUrlSegmentProviderto respect thepublishedparameter when falling back to the content name, plus add/extend tests.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| uui-range-slider-issue.md | Adds documentation about a uui-range-slider minGap=0 issue (appears unrelated to this PR’s redirect-tracking focus). |
| tests/Umbraco.Tests.UnitTests/Umbraco.Core/Strings/DefaultUrlSegmentProviderTests.cs | New unit coverage for draft vs published name fallback behavior. |
| tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/DocumentUrlServiceTests.cs | Adds tests for invariant segment resolution when culture is empty or when culture-specific entries are missing. |
| tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Routing/RedirectTrackerTests.cs | Extends integration coverage for publish/move traversal behavior, batch de-duplication, and provider override scenarios. |
| src/Umbraco.Infrastructure/Routing/RedirectTrackingHandler.cs | Passes isMove context into redirect tracking during move vs publish notifications. |
| src/Umbraco.Infrastructure/Routing/RedirectTracker.cs | Implements segment-change gating for publishes and batch de-duplication; wires in URL segment providers + document URL service. |
| src/Umbraco.Core/Strings/IUrlSegmentProvider.cs | Adds HasUrlSegmentChanged default interface method for consistent change detection across providers. |
| src/Umbraco.Core/Strings/DefaultUrlSegmentProvider.cs | Fixes name fallback to honor the published flag (draft vs published segment source). |
| src/Umbraco.Core/Services/DocumentUrlService.cs | Fixes invariant fallback behavior in GetUrlSegment/GetUrlSegments/TryGetPrimaryUrlSegment when culture can’t be resolved. |
| src/Umbraco.Core/Routing/IRedirectTracker.cs | Adds StoreOldRoute(..., isMove) overload and obsoletes the older overload. |
|
We've discussed an an edge case where the segment-unchanged optimization could break custom ScenarioA custom segment provider uses When Proposed SolutionAdded
Custom providers that derive descendant segments from ancestor data (or external sources) can override this, either returning true unconditionally, or using logic (e.g. checking the content type, level or property values) to limit traversal to affected subtrees. The built-in provider returns |
Migaroez
left a comment
There was a problem hiding this comment.
LGTM and covers all the edgecases i can think off.
…nt traversal (#22091) * Optimise redirect tracker by avoiding re-producing of descendant nodes and avoiding descendant traversal when there has been no change to the node's URL segment. * Delete inadvertently added file * Allow URL segment providers to ensure descendent traversal if needed. * Pushed missing files. * Refactors to reduce large method code smells.
Updated [Umbraco.Cms.Persistence.Sqlite](https://github.com/umbraco/Umbraco-CMS) from 17.2.2 to 17.3.0. <details> <summary>Release notes</summary> _Sourced from [Umbraco.Cms.Persistence.Sqlite's releases](https://github.com/umbraco/Umbraco-CMS/releases)._ ## 17.3.0 ## Upgrade Notes In 17.3 we have upgraded our dependency on `MailKit` to 4.15.1. This is a minor version update, but we found a few changes we had to make in core to accommodate changes to nullability constraints. Unless using methods of this library, or it's transitive dependency `MimeKit`, it's unlikely projects will be affected. The update is necessary though, as the version we previously depended on now has a security vulnerability raised against it. We have made a change to how we handle redirects which brings a significant performance improvement for publish time on large sites, when documents with many descendent nodes are published. If you have custom URL providers you should review this change, as there are some [very rare cases](umbraco/Umbraco-CMS#22091 (comment)) where you'll need to adjust to ensure descendent redirects are correctly handled. Note also that we now auto-generate HMAC secret key for new installs. This has been applied to make Umbraco more secure by default, but it's not been forced for upgrades. ## What's Changed Since 17.3.0-rc3 **Full Changelog**: umbraco/Umbraco-CMS@release-17.3.0-rc3...release-17.3.0 ## What's Changed Since 17.3.0-rc2 ### 📦 Dependencies * Dependencies: Update Microsoft packages to latest patch and fix HybridCache ParseFault with Redis by @AndyButland in umbraco/Umbraco-CMS#22278 ### 🐛 Bug Fixes * Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade by @AndyButland in umbraco/Umbraco-CMS#22243 * Unattended Upgrades: Rebuild routing caches after background migrations to fix unrouteable document URLs by @AndyButland in umbraco/Umbraco-CMS#22269 * Migrations: Fix NPoco auto-select breaking re-trust FK migration by @AndyButland in umbraco/Umbraco-CMS#22270 **Full Changelog**: umbraco/Umbraco-CMS@release-17.3.0-rc2...release-17.3.0-rc3 ## What's Changed Since 17.3.0-rc1 ### 🐛 Bug Fixes * Migrations: Fix re-trust constraints migration targeting non-Umbraco tables and transaction failure (closes #22227) by @AndyButland in umbraco/Umbraco-CMS#22229 * Distributed Locking: Add ROWLOCK hint to prevent cross-row contention on umbracoLock table (closes #22113) by @AndyButland in umbraco/Umbraco-CMS#22126 * Application URLs: Prevent back office hosts being overwritten in a shared database setup (closes #16741) by @matthewcare in umbraco/Umbraco-CMS#22160 * Migrations: Fix property detection for invariant content types with culture-varying compositions (closes #22159) by @AndyButland in umbraco/Umbraco-CMS#22167 * Migrations: Fix package migrations not running after fresh install with packages (closes #22202) by @AndyButland in umbraco/Umbraco-CMS#22204 **Full Changelog**: umbraco/Umbraco-CMS@release-17.3.0-rc...release-17.3.0-rc2 ## What's Changed Since the Previous Version (17.2.2) ### 🙌 Notable Changes * Templates: Add optional Central Package Management support to UmbracoProject and UmbracoExtension templates by @NguyenThuyLan in umbraco/Umbraco-CMS#21641 * Service registration: Allow running Umbraco with different combinations of backoffice, website and delivery API (closes #21622) by @AndyButland in umbraco/Umbraco-CMS#21630 * Imaging Configuration: Auto-generate HMAC secret key for new installs by @AndyButland in umbraco/Umbraco-CMS#21976 * Migrations: Run unattended upgrades in background, add liveness/readiness health probes (closes #21987) by @AndyButland in umbraco/Umbraco-CMS#22020 ### 💥 Breaking Changes * Dependencies: Update MailKit to 4.15.1 by @AndyButland in umbraco/Umbraco-CMS#22028 ### 📦 Dependencies * Bump lodash from 4.17.21 to 4.17.23 in /tests/Umbraco.Tests.AcceptanceTest in the npm_and_yarn group across 1 directory by @dependabot[bot] in umbraco/Umbraco-CMS#21519 ... (truncated) ## 17.3.0-rc3 ## Upgrade Notes In 17.3 we have upgraded our dependency on `MailKit` to 4.15.1. This is a minor version update, but we found a few changes we had to make in core to accommodate changes to nullability constraints. Unless using methods of this library, or it's transitive dependency `MimeKit`, it's unlikely projects will be affected. The update is necessary though, as the version we previously depended on now has a security vulnerability raised against it. We have made a change to how we handle redirects which brings a significant performance improvement for publish time on large sites, when documents with many descendent nodes are published. If you have custom URL providers you should review this change, as there are some [very rare cases](umbraco/Umbraco-CMS#22091 (comment)) where you'll need to adjust to ensure descendent redirects are correctly handled. Note also that we now auto-generate HMAC secret key for new installs. This has been applied to make Umbraco more secure by default, but it's not been forced for upgrades. ## What's Changed Since 17.3.0-rc2 ### 📦 Dependencies * Dependencies: Update Microsoft packages to latest patch and fix HybridCache ParseFault with Redis by @AndyButland in umbraco/Umbraco-CMS#22278 ### 🐛 Bug Fixes * Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade by @AndyButland in umbraco/Umbraco-CMS#22243 * Unattended Upgrades: Rebuild routing caches after background migrations to fix unrouteable document URLs by @AndyButland in umbraco/Umbraco-CMS#22269 * Migrations: Fix NPoco auto-select breaking re-trust FK migration by @AndyButland in umbraco/Umbraco-CMS#22270 **Full Changelog**: umbraco/Umbraco-CMS@release-17.3.0-rc2...release-17.3.0-rc3 ## What's Changed Since 17.3.0-rc1 ### 🐛 Bug Fixes * Migrations: Fix re-trust constraints migration targeting non-Umbraco tables and transaction failure (closes #22227) by @AndyButland in umbraco/Umbraco-CMS#22229 * Distributed Locking: Add ROWLOCK hint to prevent cross-row contention on umbracoLock table (closes #22113) by @AndyButland in umbraco/Umbraco-CMS#22126 * Application URLs: Prevent back office hosts being overwritten in a shared database setup (closes #16741) by @matthewcare in umbraco/Umbraco-CMS#22160 * Migrations: Fix property detection for invariant content types with culture-varying compositions (closes #22159) by @AndyButland in umbraco/Umbraco-CMS#22167 * Migrations: Fix package migrations not running after fresh install with packages (closes #22202) by @AndyButland in umbraco/Umbraco-CMS#22204 **Full Changelog**: umbraco/Umbraco-CMS@release-17.3.0-rc...release-17.3.0-rc2 ## What's Changed Since the Previous Version (17.2.2) ### 🙌 Notable Changes * Templates: Add optional Central Package Management support to UmbracoProject and UmbracoExtension templates by @NguyenThuyLan in umbraco/Umbraco-CMS#21641 * Service registration: Allow running Umbraco with different combinations of backoffice, website and delivery API (closes #21622) by @AndyButland in umbraco/Umbraco-CMS#21630 * Imaging Configuration: Auto-generate HMAC secret key for new installs by @AndyButland in umbraco/Umbraco-CMS#21976 * Migrations: Run unattended upgrades in background, add liveness/readiness health probes (closes #21987) by @AndyButland in umbraco/Umbraco-CMS#22020 ### 💥 Breaking Changes * Dependencies: Update MailKit to 4.15.1 by @AndyButland in umbraco/Umbraco-CMS#22028 ### 📦 Dependencies * Bump lodash from 4.17.21 to 4.17.23 in /tests/Umbraco.Tests.AcceptanceTest in the npm_and_yarn group across 1 directory by @dependabot[bot] in umbraco/Umbraco-CMS#21519 * Bump the npm_and_yarn group across 2 directories with 2 updates by @dependabot[bot] in umbraco/Umbraco-CMS#21754 * Bump qs from 6.14.1 to 6.14.2 in /src/Umbraco.Web.UI.Client in the npm_and_yarn group across 1 directory by @dependabot[bot] in umbraco/Umbraco-CMS#21755 * Dependencies: Bumps @umbraco-ui/uui from 1.17.0 to 1.17.1 by @iOvergaard in umbraco/Umbraco-CMS#22029 * Dependencies: Updates @umbraco-ui/uui to 1.17.2 to fix multiple folder drag-and-drop failing (closes #21837) by @iOvergaard in umbraco/Umbraco-CMS#21886 ... (truncated) ## 17.3.0-rc2 ## Upgrade Notes In 17.3 we have upgraded our dependency on `MailKit` to 4.15.1. This is a minor version update, but we found a few changes we had to make in core to accommodate changes to nullability constraints. Unless using methods of this library, or it's transitive dependency `MimeKit`, it's unlikely projects will be affected. The update is necessary though, as the version we previously depended on now has a security vulnerability raised against it. We have made a change to how we handle redirects which brings a significant performance improvement for publish time on large sites, when documents with many descendent nodes are published. If you have custom URL providers you should review this change, as there are some [very rare cases](umbraco/Umbraco-CMS#22091 (comment)) where you'll need to adjust to ensure descendent redirects are correctly handled. Note also that we now auto-generate HMAC secret key for new installs. This has been applied to make Umbraco more secure by default, but it's not been forced for upgrades. ## What's Changed Since 17.3.0-rc1 ### 🐛 Bug Fixes * Migrations: Fix re-trust constraints migration targeting non-Umbraco tables and transaction failure (closes #22227) by @AndyButland in umbraco/Umbraco-CMS#22229 * Distributed Locking: Add ROWLOCK hint to prevent cross-row contention on umbracoLock table (closes #22113) by @AndyButland in umbraco/Umbraco-CMS#22126 * Application URLs: Prevent back office hosts being overwritten in a shared database setup (closes #16741) by @matthewcare in umbraco/Umbraco-CMS#22160 * Migrations: Fix property detection for invariant content types with culture-varying compositions (closes #22159) by @AndyButland in umbraco/Umbraco-CMS#22167 * Migrations: Fix package migrations not running after fresh install with packages (closes #22202) by @AndyButland in umbraco/Umbraco-CMS#22204 **Full Changelog**: umbraco/Umbraco-CMS@release-17.3.0-rc...release-17.3.0-rc2 ## What's Changed Since the Previous Version (17.2.2) ### 🙌 Notable Changes * Templates: Add optional Central Package Management support to UmbracoProject and UmbracoExtension templates by @NguyenThuyLan in umbraco/Umbraco-CMS#21641 * Service registration: Allow running Umbraco with different combinations of backoffice, website and delivery API (closes #21622) by @AndyButland in umbraco/Umbraco-CMS#21630 * Imaging Configuration: Auto-generate HMAC secret key for new installs by @AndyButland in umbraco/Umbraco-CMS#21976 * Migrations: Run unattended upgrades in background, add liveness/readiness health probes (closes #21987) by @AndyButland in umbraco/Umbraco-CMS#22020 ### 💥 Breaking Changes * Dependencies: Update MailKit to 4.15.1 by @AndyButland in umbraco/Umbraco-CMS#22028 ### 📦 Dependencies * Bump lodash from 4.17.21 to 4.17.23 in /tests/Umbraco.Tests.AcceptanceTest in the npm_and_yarn group across 1 directory by @dependabot[bot] in umbraco/Umbraco-CMS#21519 * Bump the npm_and_yarn group across 2 directories with 2 updates by @dependabot[bot] in umbraco/Umbraco-CMS#21754 * Bump qs from 6.14.1 to 6.14.2 in /src/Umbraco.Web.UI.Client in the npm_and_yarn group across 1 directory by @dependabot[bot] in umbraco/Umbraco-CMS#21755 * Dependencies: Bumps @umbraco-ui/uui from 1.17.0 to 1.17.1 by @iOvergaard in umbraco/Umbraco-CMS#22029 * Dependencies: Updates @umbraco-ui/uui to 1.17.2 to fix multiple folder drag-and-drop failing (closes #21837) by @iOvergaard in umbraco/Umbraco-CMS#21886 * Backoffice: Update vite from 7.1.11 to 7.3.1 by @iOvergaard in umbraco/Umbraco-CMS#22065 * Dependencies: Update server-side dependencies to latest patch or minor releases by @AndyButland in umbraco/Umbraco-CMS#21860 ### 🚤 Performance * Performance: Implement key-based caching for data type and template repositories by @AndyButland in umbraco/Umbraco-CMS#21280 * Management API: Optimize collection view performance by eliminating N+1 patterns by @AndyButland in umbraco/Umbraco-CMS#21684 * Performance: Optimize handling of content type updates by @kjac in umbraco/Umbraco-CMS#21910 * Backoffice Performance: Add inflight request deduplication to item data request managers by @madsrasmussen in umbraco/Umbraco-CMS#21767 * URL and Alias Caches: Optimize for invariant documents by @AndyButland in umbraco/Umbraco-CMS#21558 * Custom Views: Prevent re-rendering Block Views and Properties by @rickbutterfield in umbraco/Umbraco-CMS#21186 * Core: Minimize await to a single JS cycle (refactor #21186) by @nielslyngsoe in umbraco/Umbraco-CMS#22074 * Auth: Skip /token refresh when access token is still valid by @iOvergaard in umbraco/Umbraco-CMS#22087 * Memory Management: Dispose `IDisposable` resources correctly in four internal classes by @AndyButland in umbraco/Umbraco-CMS#22014 * Redirect Tracking: Fix segment change detection and optimise descendant traversal (closes #22082) by @AndyButland in umbraco/Umbraco-CMS#22091 ... (truncated) ## 17.3.0-rc ## Upgrade Notes In 17.3 we have upgraded our dependency on `MailKit` to 4.15.1. This is a minor version update, but we found a few changes we had to make in core to accommodate changes to nullability constraints. Unless using methods of this library, or it's transitive dependency `MimeKit`, it's unlikely projects will be affected. The update is necessary though, as the version we previously depended on now has a security vulnerability raised against it. We have made a change to how we handle redirects which brings a significant performance improvement for publish time on large sites, when documents with many descendent nodes are published. If you have custom URL providers you should review this change, as there are some [very rare cases](umbraco/Umbraco-CMS#22091 (comment)) where you'll need to adjust to ensure descendent redirects are correctly handled. Note also that we now auto-generate HMAC secret key for new installs. This has been applied to make Umbraco more secure by default, but it's not been forced for upgrades. ## What's Changed ### 🙌 Notable Changes * Templates: Add optional Central Package Management support to UmbracoProject and UmbracoExtension templates by @NguyenThuyLan in umbraco/Umbraco-CMS#21641 * Service registration: Allow running Umbraco with different combinations of backoffice, website and delivery API (closes #21622) by @AndyButland in umbraco/Umbraco-CMS#21630 * Imaging Configuration: Auto-generate HMAC secret key for new installs by @AndyButland in umbraco/Umbraco-CMS#21976 * Migrations: Run unattended upgrades in background, add liveness/readiness health probes (closes #21987) by @AndyButland in umbraco/Umbraco-CMS#22020 ### 💥 Breaking Changes * Dependencies: Update MailKit to 4.15.1 by @AndyButland in umbraco/Umbraco-CMS#22028 ### 📦 Dependencies * Bump lodash from 4.17.21 to 4.17.23 in /tests/Umbraco.Tests.AcceptanceTest in the npm_and_yarn group across 1 directory by @dependabot[bot] in umbraco/Umbraco-CMS#21519 * Bump the npm_and_yarn group across 2 directories with 2 updates by @dependabot[bot] in umbraco/Umbraco-CMS#21754 * Bump qs from 6.14.1 to 6.14.2 in /src/Umbraco.Web.UI.Client in the npm_and_yarn group across 1 directory by @dependabot[bot] in umbraco/Umbraco-CMS#21755 * Dependencies: Bumps @umbraco-ui/uui from 1.17.0 to 1.17.1 by @iOvergaard in umbraco/Umbraco-CMS#22029 * Dependencies: Updates @umbraco-ui/uui to 1.17.2 to fix multiple folder drag-and-drop failing (closes #21837) by @iOvergaard in umbraco/Umbraco-CMS#21886 * Backoffice: Update vite from 7.1.11 to 7.3.1 by @iOvergaard in umbraco/Umbraco-CMS#22065 * Dependencies: Update server-side dependencies to latest patch or minor releases by @AndyButland in umbraco/Umbraco-CMS#21860 ### 🚤 Performance * Performance: Implement key-based caching for data type and template repositories by @AndyButland in umbraco/Umbraco-CMS#21280 * Management API: Optimize collection view performance by eliminating N+1 patterns by @AndyButland in umbraco/Umbraco-CMS#21684 * Performance: Optimize handling of content type updates by @kjac in umbraco/Umbraco-CMS#21910 * Backoffice Performance: Add inflight request deduplication to item data request managers by @madsrasmussen in umbraco/Umbraco-CMS#21767 * URL and Alias Caches: Optimize for invariant documents by @AndyButland in umbraco/Umbraco-CMS#21558 * Custom Views: Prevent re-rendering Block Views and Properties by @rickbutterfield in umbraco/Umbraco-CMS#21186 * Core: Minimize await to a single JS cycle (refactor #21186) by @nielslyngsoe in umbraco/Umbraco-CMS#22074 * Auth: Skip /token refresh when access token is still valid by @iOvergaard in umbraco/Umbraco-CMS#22087 * Memory Management: Dispose `IDisposable` resources correctly in four internal classes by @AndyButland in umbraco/Umbraco-CMS#22014 * Redirect Tracking: Fix segment change detection and optimise descendant traversal (closes #22082) by @AndyButland in umbraco/Umbraco-CMS#22091 ### 🌈 Accessibility Improvements * Entity Actions: Adds a descriptive title to the first action so you know what it does by @iOvergaard in umbraco/Umbraco-CMS#21739 * Search field: Added aria-label and name to search input for accessibility (closes #21938) by @andreaslborg in umbraco/Umbraco-CMS#21962 * List view: Added labels entity bulk action buttons by @andreaslborg in umbraco/Umbraco-CMS#21964 * Accessibility: Add title attributes to buttons in block list entry and property editor UI by @manutdkid77 in umbraco/Umbraco-CMS#21842 * Accessibility: Add tooltips to block grid entry actions by @manutdkid77 in umbraco/Umbraco-CMS#21958 * Accessibility: Added `title` attribute for icon in content types by @TechPdo in umbraco/Umbraco-CMS#21956 ### 🚀 New Features ... (truncated) Commits viewable in [compare view](umbraco/Umbraco-CMS@release-17.2.2...release-17.3.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alexander Seeliger <alexsee@users.noreply.github.com>
Prerequisites
Description
This PR addresses #22082 by optimising the redirect tracker.
As part of that work, I've found and fixed a couple of bugs that would otherwise prevent URL redirects from being created when content is renamed.
Changes
1. Optimisation: Skip descendant traversal when URL segment is unchanged
The main problem I feel is that we are currently checking to create redirects for the node and it's descendants on every save and publish. In the vast majority of these cases, no redirects are needed and so this is wasteful. On the other hand, we can't just simply check if the node name or
umbracoUrlNameproperty has changed, as whilst out of the box that's all that impacts the generated URL segment. URL segment providers are extensible, so we can't know what factors might go into calculating the URL segment.To resolve this I've used the segment providers themselves to find the new segment, compared it to the old, and if they are the same, early return to not carry out the unnecessary traversal of descendent nodes. If the segment is unchanged, no descendant URLs can have changed either, so the entire traversal is skipped.
This is implemented via a new
IUrlSegmentProvider.HasUrlSegmentChangedmethod with a default interface implementation, replacing a long-standing TODO comment. The intention is that this a permanent default implementation, so only providers that need to update this behaviour need to implement it.The
IRedirectTracker.StoreOldRoutemethod has a newbool isMoveoverload so the handler can distinguish publishes from moves — moves will still always traverse descendants since the parent path changes.2. Optimisation: Batch deduplication of already-processed descendants
When multiple content items are published in a batch and a parent's traversal already processed a child, the child's subsequent
StoreOldRoutecall is skipped by checking if its ID is already in theoldRoutesdictionary.3. Bug fix:
DocumentUrlService.GetUrlSegmentreturned null for invariant contentGetUrlSegmentandGetUrlSegmentsreturned null/empty when called with an empty culture string for invariant content. Invariant content is stored with a null language ID in the cache, butTryGetLanguageIdFromCulture("")fails — the code previously returned early at that point. Now it falls through to the invariant (null language ID) cache lookup.TryGetPrimaryUrlSegmenthad the same issue and is fixed identically.4. Bug fix:
DefaultUrlSegmentProviderignoredpublishedparameter in name fallbackWhen content has no
umbracoUrlNameproperty,GetUrlSegmentSourcefalls back to the content name. The fallback had a special case: ifdocument.Editedis true and a published name exists, always return the published name — regardless of thepublishedparameter. This meantGetUrlSegment(content, published: false, culture)returned the old published name instead of the current draft name.This broke redirect tracking:
HasUrlSegmentChangedcompares the currently-published segment against what the segment will be after publishing (draft values), but both sides returned the published name, so no change was ever detected for invariant content.The fix adds
published &&to the condition so the published-name preference only applies whenpublished: trueis requested. Whenpublished: false, the current (draft) name is returned — consistent with how theumbracoUrlNameproperty path already behaved.Testing
Automated
The various unit and integration tests added in this PR, plus existing ones for these classes, should pass.
Manual
Invariant content — rename and publish
/original-name/original-name→/new-name/original-name— should redirect to/new-nameVariant content — rename and publish
Move operation — verify descendants are tracked
/parent/child)No-change publish — verify no unnecessary work
RedirectTracker(line 89) and verify that the method early returns to avoid the unnecessary work.Documentation
We should document
MayAffectDescendantSegmentsonIUrlSegmentProvider.